/*----------------------------------------------*
 * 包含头文件                                   *
 *----------------------------------------------*/
#include "bsp_dbg_uart.h"
#include "cola_device.h"
#include "cola_init.h"
#include "cola_fifo.h"
#include "shell_port.h"

#include "sdk_project_config.h"
#include <stdio.h>
#include <string.h>


/*----------------------------------------------*
 * 宏定义                                 *
 *----------------------------------------------*/
#define DBG_UART_RX_BUF_LEN		256
/*----------------------------------------------*
 * 枚举定义                            *
 *----------------------------------------------*/

/*----------------------------------------------*
 * 结构体定义                              *
 *----------------------------------------------*/

/*----------------------------------------------*
 * 全局变量                                     *
 *----------------------------------------------*/
/** \var  	s_bsp_dbg_uart_dev
 *  \brief 	debug uart的操作句柄
 */
static cola_device_t s_bsp_dbg_uart_dev;

/** \var  	s_bsp_dbg_uart_rx_buf_handle
 *  \brief 	debug uart rx ringbuf的操作句柄
 */

static cola_fifo_t s_bsp_dbg_uart_rx_buf_handle;

/** \var  	s_bsp_dbg_uart_rx_buf
 *  \brief 	debug uart rx ringbuf
 */
static uint8_t s_bsp_dbg_uart_rx_buf[DBG_UART_RX_BUF_LEN];

/* Timeout in ms for blocking operations */
#define TIMEOUT     500U

/* Receive buffer size */
#define BUFFER_SIZE 256U
#define uart_instance     uart_instance_lu1
#define UART_PAL_CONFIG   &LPUART_1_uart_pal_config0

/* Buffer used to receive data from the console */
uint8_t RX_buffer[BUFFER_SIZE];
uint8_t bufferIdx;
uint8_t recv_buf = 0;
/** \var  	s_bsp_dbg_uart_dev
 *  \brief 	debug uart的操作句柄
 */
static struct cola_device_ops bsp_dbg_uart_ops =
{
    .open   = bsp_dbg_uart_open,
    .close  = bsp_dbg_uart_close,
    .write  = bsp_dbg_uart_write,
    .read   = bsp_dbg_uart_read
};


/*----------------------------------------------*
 * 函数原型说明                                     *
 *----------------------------------------------*/


/* UART rx callback for continuous reception, byte by byte */
void rxCallback(void *driverState, uart_event_t event, void *userData)
{
    /* Unused parameters */
    (void)driverState;
    (void)userData;

    /* Check the event type */
    if (event == UART_EVENT_RX_FULL)
    {
        /* The reception stops when newline is received or the buffer is full */
        if ((RX_buffer[bufferIdx] != '\n') && (bufferIdx != (BUFFER_SIZE - 2U)))
        {
            /* Update the buffer index and the rx buffer */
            bufferIdx++;
            UART_SetRxBuffer(&uart_instance, &RX_buffer[bufferIdx], 1U);

        }
    }
	;
}



/**
 * @brief  DBG USART RX IRQ callback
 * @param  None
 * @return None
 */


/**
 * @brief  debug uart open.
 * @param  [in] cola_device_t *dev 设备操作句柄
 * @param  [in] int oflag 无效参数
 * @return None
 */
int bsp_dbg_uart_open(cola_device_t *dev, int oflag)
{
	(void)dev;
	(void)oflag;
    // 初始化接收fifo
    cola_fifo_init(&s_bsp_dbg_uart_rx_buf_handle, s_bsp_dbg_uart_rx_buf, DBG_UART_RX_BUF_LEN);

    bsp_dbg_uart_init_uart();

    return 0;
}

/**
 * @brief  debug uart close.
 * @param  [in] cola_device_t *dev 设备操作句柄
 * @return None
 */
int bsp_dbg_uart_close(cola_device_t *dev)
{
	(void)dev;
    bsp_dbg_uart_deinit_uart();

    // 清空数据
    cola_fifo_flush(&s_bsp_dbg_uart_rx_buf_handle);
    return 0;
}
 
/**
 *@brief 向串口写入数据
 *
 *@param cola_device_t *dev 设备句柄
 *@param int pos 操作类型
 *@param void *buffer 缓存空间
 *@param int size 缓存空间大小
 *
 *@return int 写入的结果
 *
 */
int bsp_dbg_uart_write(cola_device_t *dev, int pos, const void *buffer, int size)
{
	(void)dev;
	(void)pos;
    if (!buffer || (size == 0))
    {
        return 0;
    }
    UART_SendDataBlocking(&uart_instance, buffer, size, TIMEOUT);
    return 0;
}

/**
 *@brief 从串口读取数据
 *
 *@param cola_device_t *dev 设备句柄
 *@param int pos 操作类型
 *@param void *buffer 缓存空间
 *@param int size 缓存空间大小
 *
 *@return int 读入的长度
 *
 */

int bsp_dbg_uart_read(cola_device_t *dev, int pos, void *buffer, int size)
{
	(void)dev;
	(void)pos;
	(void)buffer;
	(void)size;
    UART_ReceiveData(&uart_instance, RX_buffer, 1U);
    return 0;
}


/**
 *@brief 串口初始化
 *
 *@param none
 *
 *@return none
 *
 */
void bsp_dbg_uart_init_uart(void)
{
	  UART_Init(&uart_instance, UART_PAL_CONFIG);

#if 0
	LPUART_DRV_Init(INST_LPUART_0, &lpUartState0, &lpuart_0_InitConfig0);
	LPUART_DRV_InstallRxCallback(INST_LPUART_0, rxCallback, NULL);
	//printf("hello\r\n");
#endif
}
/**
 *@brief 串口去初始化
 *
 *@param none
 *
 *@return none
 *
 */
void bsp_dbg_uart_deinit_uart(void)
{
    
}

int _write(int fd, char *buf, int nbytes)
{
	(void)fd;
    UART_SendDataBlocking(&uart_instance, (const uint8_t *)buf, (uint32_t)nbytes, TIMEOUT);

	//LPUART_DRV_SendDataBlocking(INST_LPUART_0, buf, nbytes, TIMEOUT);
    return nbytes;
}


void bsp_dbg_uart_read_uart(void)
{
#if 0
	/* Write your local variable definition here */
	status_t status;
	/* Declare a buffer used to store the received data */
	uint32_t bytesRemaining;
	/* Check the status */
	status = LPUART_DRV_GetReceiveStatus(INST_LPUART_0, &bytesRemaining);

	if (status != STATUS_SUCCESS)
	{
	  /* If an error occurred, send the error message and exit the loop */
	  //LPUART_DRV_SendDataBlocking(INST_LPUART_0, (uint8_t *)errorMsg, strlen(errorMsg), TIMEOUT);
	  //break;
	}

	/* Append string terminator to the received data */
	bufferIdx++;
	buffer[bufferIdx] = 0U;

	/* If the received string is "Hello Board", send back "Hello World" */
	if(strcmp((char *)buffer, "Hello Board\n") == 0)
	{
	  strcpy((char *)buffer, "Hello World\n");
	}

	/* Send the received data back */
	LPUART_DRV_SendDataBlocking(INST_LPUART_0, buffer, bufferIdx, TIMEOUT);
	/* Reset the buffer index to start a new reception */
	bufferIdx = 0U;
#endif
}


/**
 *@brief debug uart适配的挂载
 *
 *@param none
 *@return none
 *
 */
void bsp_dbg_uart_configuration(void)
{
    s_bsp_dbg_uart_dev.name = "dbg_uart";
    s_bsp_dbg_uart_dev.dops = &bsp_dbg_uart_ops;
    cola_device_register(&s_bsp_dbg_uart_dev);
}
register_initcall(bsp_dbg_uart_configuration);
